package aole.visq.draw;

import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.beans.Transient;
import java.util.HashMap;

import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;

public class AnimationPanel extends JPanel implements MouseListener,
		MouseMotionListener {
	private static final long	serialVersionUID	= 1L;

	private int					sideMargin			= 10;
	private int					verticalMargin		= 5;
	private int					animationWidth;
	private int					currentFrame		= 1;
	private static BasicStroke	line1				= new BasicStroke( 1 );
	private static BasicStroke	line3				= new BasicStroke( 3 );
	private DrawApp				app;
	private JPanel				pnlScale;

	public AnimationPanel( DrawApp a ) {
		super( new BorderLayout() );
		app = a;

		pnlScale = new JPanel() {
			private static final long	serialVersionUID	= 1L;

			protected void paintComponent( Graphics g ) {
				super.paintComponent( g );
				Graphics2D g2 = (Graphics2D) g;
				int x = sideMargin;
				int x2 = getWidth() - sideMargin;
				int h = getHeight();
				int ym = h / 2;
				// draw middle horizontal line
				g2.setStroke( line1 );
				g2.setColor( Color.BLACK );
				g2.drawLine( x, ym, x2, ym );

				HashMap< Integer, ? extends Object > keys = app.getKeys();

				// draw vertical frame lines
				float w = (getWidth() - sideMargin * 2f)
						/ (animationWidth - 1f);
				for( int i = 0; i < animationWidth; i++ ) {
					// draw frame line and number
					if( keys.get( i + 1 ) != null ) {
						g2.drawOval( (int) (x + i * w),
								(int) (verticalMargin + 4), 4, 4 );
					} else {
						g2.drawLine( (int) (x + i * w), (int) (verticalMargin),
								(int) (x + i * w), ym );
					}
					g2.drawString( (i + 1) + "", (int) (x - 6 + i * w), h
							- verticalMargin );
					// draw current frame line
					if( (i + 1) == currentFrame ) {
						g2.setStroke( line3 );
						g2.setColor( Color.RED );
						g2.drawLine( (int) (x - 1 + i * w), verticalMargin,
								(int) (x - 1 + i * w), h - verticalMargin );
						g2.setColor( Color.BLACK );
						g2.drawString( (i + 1) + "", (int) (x - 6 + i * w), h
								- verticalMargin );
						g2.setStroke( line1 );
					}
				}
			}
		};
		pnlScale.addMouseListener( this );
		pnlScale.addMouseMotionListener( this );
		
		JButton btnSetKey = new JButton(
				DrawApp.getIcon( "/images/size24/key.png" ) );
		btnSetKey.setActionCommand( "key_set" );
		btnSetKey.addActionListener( app );
		
		JButton btnRemoveKey = new JButton(
				DrawApp.getIcon( "/images/size24/list_remove.png" ) );
		btnRemoveKey.setActionCommand( "key_remove" );
		btnRemoveKey.addActionListener( app );
		
		JToggleButton btnPlay = new JToggleButton(
				DrawApp.getIcon( "/images/size24/playback_play.png" ) );
		btnPlay.setActionCommand( "animation_play" );
		btnPlay.addActionListener( app );
		
		JToolBar tb = new JToolBar();
		tb.setFloatable( false );
		tb.add( btnSetKey );
		tb.add( btnRemoveKey );
		tb.add( btnPlay );

		add( pnlScale, BorderLayout.CENTER );
		add( tb, BorderLayout.EAST );
	}

	@Override
	@Transient
	public Dimension getPreferredSize() {
		return new Dimension( 0, 32 );
	}

	public void setAnimationWidth( int width ) {
		animationWidth = width;
		repaint();
	}

	public void setCurrentFrame( int frame ) {
		currentFrame = frame;
		repaint();
	}

	public int getCurrentFrame() {
		return currentFrame;
	}

	public void mouseClicked( MouseEvent e ) {}

	public void mouseEntered( MouseEvent e ) {}

	public void mouseExited( MouseEvent e ) {}

	public void mousePressed( MouseEvent e ) {
		int x = e.getX() - sideMargin;
		float fw = (pnlScale.getWidth() - sideMargin * 2)
				/ ((float) animationWidth - 1);
		int f = (int) ((x / fw) + 1.5f);
		app.currentFrameChanged( f );
	}

	public void mouseReleased( MouseEvent e ) {}

	public void mouseMoved( MouseEvent e ) {}

	public void mouseDragged( MouseEvent e ) {
		int x = e.getX() - sideMargin;
		float fw = (pnlScale.getWidth() - sideMargin * 2)
				/ ((float) animationWidth - 1);
		int f = (int) ((x / fw) + 1.5f);
		app.currentFrameChanged( f );
	}
}